package org.ezplatform.office.meeting.memo.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.ezplatform.cloud.api.component.attachment.AttachmentUtilsService;
import org.ezplatform.cloud.api.component.popuser.PopUserScopeUtilService;
import org.ezplatform.cloud.api.system.user.UserApiService;
import org.ezplatform.cloud.common.client.RestClient;
import org.ezplatform.core.common.WebUser;
import org.ezplatform.core.dao.jpa.JpaBaseDao;
import org.ezplatform.core.service.BaseService;
import org.ezplatform.core.web.util.WebUtils;
import org.ezplatform.core.web.view.OperationResult;
import org.ezplatform.office.meeting.common.util.MeetingUtils;
import org.ezplatform.office.meeting.info.entity.ApplyRecord;
import org.ezplatform.office.meeting.info.entity.MeetingScope;
import org.ezplatform.office.meeting.info.service.MeetingScopeService;
import org.ezplatform.office.meeting.memo.dao.MemoInfoDao;
import org.ezplatform.office.meeting.memo.dao.MemoUserInfoDao;
import org.ezplatform.office.meeting.memo.entity.MemoInfo;
import org.ezplatform.office.meeting.memo.entity.MemoUserInfo;
import org.ezplatform.util.DateUtils;
import org.ezplatform.util.JsonUtils;
import org.ezplatform.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;

@Service
@Transactional
public class MemoInfoService extends BaseService<MemoInfo, String>{
    
    @Autowired
    private MemoInfoDao dao;
    
    @Autowired
    private MemoUserInfoDao memoUserInfoDao;
    @Lazy
    @Autowired
    private MemoUserInfoService memoUserInfoService;

//    @Autowired
//    private ApplyRecordService applyRecordService;
    
    @Autowired
	private AttachmentUtilsService attachmentUtilsService;
    
    @Autowired
   	private PopUserScopeUtilService popUserScopeUtilService;
    @Lazy
    @Autowired
   	private MeetingScopeService meetingScopeService;
    
    @Autowired
   	private UserApiService userApiService;
    
    @Autowired
	private RestClient restClient;
    
//    @Autowired
//   	private OrgApiService orgApiService;
    
    private int currentPageNum = 0;
    private int pageSizeNum = 0;
    private int startLimitNum = 0;

    @Override
    protected JpaBaseDao<MemoInfo, String> getEntityDao() {
        return dao;
    }
    
    /**
     * 会议纪要列表
     * @param pageable
     * @param corpId
     * @param title
     * @param isView
     * @return
     */
    public Page findByPage(Pageable pageable, String userId, String corpId, String title, int isView) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		StringBuffer sql = new StringBuffer();
		sql.append("select mi.id memoId,mi.apply_record_id applyRecordId,mui.id id,ar.name,u.user_name,mi.createdDate from oa_meeting_memo_info mi");
		sql.append(" inner join oa_meeting_memo_user_info mui on mi.id=mui.memo_id ");
		sql.append(" and mi.corp_id=:corpId and mui.is_view=:isView and mui.memo_user_id=:userId ");
		
		sql.append(" left join oa_meeting_apply_record ar on ar.id=mi.apply_record_id");
		sql.append(" left join sys_user u on mi.createdBy=u.id");
		sql.append(" where 1=1 ");
		
		if(StringUtils.isNotBlank(title)) {
			sql.append(" and ar.name like :title");
			paramMap.put("title", "%"+ title +"%");
		}
		sql.append(" order by mi.createdDate desc");
		paramMap.put("userId", userId);
		paramMap.put("corpId", corpId);
		paramMap.put("isView", isView);
		return super.findByPageNativeSQL(pageable, sql.toString(), paramMap);
	}
    
    /**
     * 保存会议纪要
     * @param entity
     * @return 
     */
    public OperationResult saveMemoInfo(MemoInfo entity, List<String> userIdList, String corpId) {
        String id = entity.getId();
        entity = this.save(entity);
        String memoId = entity.getId();
        //编辑时需要检测纪要通知的人有没有增减
        if(StringUtils.isNotBlank(id)){
        	List<MemoUserInfo> memoUserInfoList = memoUserInfoDao.getMemoUserInfoByMemoId(id, corpId);
        	List<String> addList = new ArrayList<String>();
			List<MemoUserInfo> deleteList = new ArrayList<MemoUserInfo>();
			List<String> ids = new ArrayList<String>();
			for(MemoUserInfo mui : memoUserInfoList) {
				//老的id不在新的id集合里面，说明已删除
				if(!userIdList.contains(mui.getMemoUserId())) {
					deleteList.add(mui);
				}
				ids.add(mui.getId());
			}
			for(String userId : userIdList) {
				//老的id集合不包含新的id，说明新的id是新增的
				if(!ids.contains(userId)) {
					addList.add(userId);
				}
			}
			this.memoUserInfoService.delete(deleteList);
			this.memoUserInfoService.addMemoUserInfo(memoId, addList, corpId);
        }else {
        	this.memoUserInfoService.addMemoUserInfo(memoId, userIdList, corpId);
        }
        return OperationResult.buildSuccessResult("保存成功");
    }
    
    /**
     * 查询会议纪要所有需要通知的用户(带去重的)
     * @param applyRecord
     * @param memoInfo
     * @param token
     * @return
     */
    public List<String> getMemoInfoUserList(ApplyRecord applyRecord, MemoInfo memoInfo, String token){
        String corpId = applyRecord.getCorpId();
//        //主持人
//        List<String> eScopeList = new ArrayList<>();
//        eScopeList.add(applyRecord.getEmceeUser());
//        List<MeetingScope> emceeUserList = this.meetingScopeService.getMeetingScopeList("oa_meeting_apply_record", "emcee_user", eScopeList,true);
//        //纪要员
//        List<String> mScopeList = new ArrayList<>();
//        mScopeList.add(applyRecord.getMemoUser());
//        List<MeetingScope> memoUserList = this.meetingScopeService.getMeetingScopeList("oa_meeting_apply_record", "memo_user", mScopeList,true);
//        //参会员
//        List<String> aScopeList = new ArrayList<>();
//        aScopeList.add(applyRecord.getAttendUser());
//        List<MeetingScope> attendUserList = this.meetingScopeService.getMeetingScopeList("oa_meeting_apply_record", "attend_user", aScopeList,true);
//        //会议纪要产看范围内的人
//        List<String> sScopeList = new ArrayList<>();
//        sScopeList.add(memoInfo.getMemoUser());
//        List<MeetingScope> memoInfoUserList = this.meetingScopeService.getMeetingScopeList("oa_meeting_memo_info", "memo_scope", sScopeList,true);
        //主持人、纪要员、参会员
        List<String> scopeList= new ArrayList<>();
        scopeList.add(applyRecord.getEmceeUser());
        scopeList.add(applyRecord.getMemoUser());
        scopeList.add(applyRecord.getAttendUser());
        String sqlWhereFieldDataValue1=MeetingUtils.getWhereInValuesSql("fieldDataValue", scopeList, 1000);
        List<String> sScopeList = new ArrayList<>();
        //会议纪要查看范围内的人
        sScopeList.add(memoInfo.getMemoUser());
        String sqlWhereFieldDataValue2=MeetingUtils.getWhereInValuesSql("fieldDataValue", sScopeList, 1000);
        StringBuffer sb=new StringBuffer();
        sb.append("select scopeType,scopeValue from oa_meeting_apply_record_scope t where t.fieldDataTable='oa_meeting_apply_record' and (t.fieldData='attend_user' or t.fieldData='emcee_user' or t.fieldData='memo_user')and ");
        sb.append(sqlWhereFieldDataValue1);
        sb.append("union select scopeType,scopeValue from oa_meeting_apply_record_scope t where t.fieldDataTable='oa_meeting_memo_info' and t.fieldData='memo_scope' and ");
        sb.append(sqlWhereFieldDataValue2);
        List<Map> applyUserList=this.meetingScopeService.findByListNativeQuery(sb.toString(),null);
        
        Set<String> userList = new HashSet<String>();
//        getScopeValueSet(userList, emceeUserList, corpId, token);
//        getScopeValueSet(userList, memoUserList, corpId, token);
//        getScopeValueSet(userList, attendUserList, corpId, token);
//        getScopeValueSet(userList, memoInfoUserList, corpId, token);
        getScopeValueSet(userList, applyUserList, corpId, token);
        return new ArrayList<String>(userList);
    }
    
    private void getScopeValueSet(Set<String> set, List<Map> list, String corpId, String token){
    	if(CollectionUtils.isNotEmpty(list)){
            for(Map ms : list){
                String scopeValue = (String)ms.get("scopeValue");
                String scopeType = (String)ms.get("scopeType");
                List<String> unitUserList = null;
                if("user".equals(scopeType)){
                	set.add(scopeValue);
                }else if("org".equals(scopeType)){
                	unitUserList = this.userApiService.getUserIdsByOrgId(scopeValue, "", "1", corpId, token);
                    if(CollectionUtils.isNotEmpty(unitUserList)){
                    	set.addAll(unitUserList);
                    }
                }else if("group".equals(scopeType)){
                	unitUserList = this.userApiService.getUserIdsByGrpId(scopeValue, "1", corpId, token);
                    if(CollectionUtils.isNotEmpty(unitUserList)){
                    	set.addAll(unitUserList);
                    }
                }else if("station".equals(scopeType)){
                	unitUserList = this.userApiService.getUserIdsByStationId(scopeValue, "1", corpId, token);
                    if(CollectionUtils.isNotEmpty(unitUserList)){
                    	set.addAll(unitUserList);
                    }
                }
            }
        }
    }
    
    /**
     * 根据会议id删除会议纪要信息
     * @param recordIds
     */
    public OperationResult deleteMemoInfo(String... recordIds){
    	List<MemoInfo> list = this.dao.findMemoInfoByRecordId(recordIds);
    	if(CollectionUtils.isNotEmpty(list)){
    		List<String> memoIds = new ArrayList<String>();
    		for(MemoInfo mi : list) {
    			memoIds.add(mi.getId());
    			this.popUserScopeUtilService.delScopeMethod("oa_meeting_apply_record_scope", mi.getMemoUser(), "oa_meeting_memo_info", "memo_scope");
    		}
    		this.memoUserInfoDao.deleteMemoUserInfo(memoIds);
        	this.dao.delByRecordId(recordIds);
    	}
    	return OperationResult.buildSuccessResult("删除成功");
    }
    
    /**
     * 查询会议纪要列表数据
     * @param currentPage
     * @param pageSize
     * @param userId
     * @param corpId
     * @param string
     * @param condition
     * @param type
     * @return
     */
    public List<Map> getMemoInfoList(String currentPage, String pageSize, String userId, String corpId,
            String isCountType, String condition, String type) {
        List<Map> list = new ArrayList<>();
        
        StringBuffer sql = new StringBuffer();
        Map<String, Object> params = new HashMap<>();
        params.put("corpId", corpId);
        params.put("userId", userId);
        sql.append("select ommi.id,ommui.id memoUserInfoId,omar.id applyRecordId,omar.name,omar.start_time startDateTime,");
        sql.append("omar.end_time endDateTime,ombs.address address from oa_meeting_memo_user_info ommui ");
        sql.append("left join oa_meeting_memo_info ommi on ommui.memo_id = ommi.id ");
        sql.append("left join oa_meeting_apply_record omar on ommi.apply_record_id = omar.id ");
        sql.append("left join oa_meeting_boardroom_set ombs on omar.boardroom_id = ombs.id ");
        sql.append("where ommui.corp_id =:corpId and ommui.memo_user_id =:userId and omar.id is not null ");
        
        if(type.equals("0")){
            sql.append("and ommui.is_view=0 ");
        }else if(type.equals("1")){
            sql.append("and ommui.is_view=1 ");
        }
        if(StringUtils.isNotBlank(condition)){
            sql.append("and (omar.name like :condition) ");
            params.put("condition", "%"+condition+"%");
        }
        sql.append("order by ommui.createdDate desc ");

        if(isCountType.equals("0")){
            if(StringUtils.isNotBlank(currentPage)){
                this.currentPageNum = Integer.valueOf(currentPage);
            }
            if(StringUtils.isNotBlank(pageSize)){
                this.pageSizeNum = Integer.valueOf(pageSize);
            }
           this.startLimitNum= (this.currentPageNum-1) * this.pageSizeNum;
           list = super.findByListNativeQuery(sql.toString(), "", params, this.startLimitNum, this.pageSizeNum);
        }else{
            list = super.findByListNativeQuery(sql.toString(), "", params);
        }

        if("0".equals(isCountType)){
        	if(list!=null && list.size()>0){
        		Locale localeCN = Locale.SIMPLIFIED_CHINESE;
                SimpleDateFormat format = new SimpleDateFormat("E",localeCN);
                for(Map<String,Object> map : list){
                    String startDateTime = String.valueOf(map.get("startDateTime"));
                    String endDateTime = String.valueOf(map.get("endDateTime"));
                   if(startDateTime != null){
                   	   String week = format.format(DateUtils.parseDate(startDateTime));
                       String day = DateUtils.formatDate(DateUtils.parseDate(startDateTime), "MM")+"."+DateUtils.formatDate(DateUtils.parseDate(startDateTime), "dd");
                       map.put("startDate", startDateTime.substring(5,startDateTime.length()));
                       map.put("endDate", endDateTime.substring(5,endDateTime.length()));
                       map.put("day", day);
                       map.put("week", week);
                       map.put("startTime", startDateTime.substring(11, 16));
                       map.put("endTime", endDateTime.substring(11, 16));
                   }
                }
            }
        }
        return list;
    }
    
    /**
     * 未读会议纪要数量
     * @param userId
     * @param corpId
     * @return
     */
    public int getMemoInfoListCount(String userId, String corpId) {
        return this.memoUserInfoDao.countMemoUserInfo(userId, corpId);
    }
    
    /**
     * 查询会议关联的会议纪要
     * @param applyRecordId
     * @return
     */
    public MemoInfo getMemoInfoByApplyRecordId(String applyRecordId) {
        List<MemoInfo> list = this.dao.getMemoInfoByApplyRecordId(applyRecordId);
        if(list!=null && list.size()>0){
            return list.get(0);
        }
        return null;
    }
    
    /**
	 * 获取附件信息
	 * 
	 * @param attachmentId
	 * @param token
	 * @return
	 */
	public String getAttachmentName(String attachmentId) {
		if (StringUtils.isNotBlank(attachmentId)) {
			return "[" + this.attachmentUtilsService.getAttachmentInfo(attachmentId, this.getToken()) + "]";
		}
		return "";
	}
	
	/**
	 * 根据附件id获取到附件的具体信息,并封装成钉钉app适应的格式
	 * @param attid 附件id用|分割
	 * @return
	 */
	public Object transformAttachmentPlanform2Dd(String attid, String token) {
		Object data = new JSONArray();
		if (StringUtils.isNotBlank(attid)) {
			Map param2 = new HashMap();
			param2.put("fids", attid);
			try {
				String scopeMap1 = restClient.get("/cmp/attachment/getAttachmentInfos", token, param2);
				Map<String, Object> map1 = JsonUtils.readValue(scopeMap1);
				if (StringUtils.equals("success", StringUtils.null2String(map1.get("type")))) {
					data = map1.get("data");
				}
			} catch (Exception e) {
				e.printStackTrace();
//				System.out.println("钉钉APP获取附件获取失败");
//				System.out.println(e.getMessage());
			}
		}
		return data;
	}
}